'use client';

import type { IDifference, ISendMessageBody } from '@/interfaces';
import { sendMessage } from '@/services/api';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import {
  type ChangeEvent,
  type FormEvent,
  useContext,
  useEffect,
  useRef,
  useState,
} from 'react';
import diff from 'microdiff';
import useToast from '@/hooks/useToast';
import type { TBody } from '@/types';
import {
  cleanFormData,
  getDiffData,
  getFilterData,
  isEmpty,
  isNum,
} from '@/lib/tool';
import { MessageAdminContext } from '@/contexts/admin/message';
import Editor from '@/app/[locale]/editor/wrapper';

export default function CreateMessageAdminPage() {
  const { show } = useToast();
  const [form, setForm] = useState<ISendMessageBody>({
    name: '',
    content: '',
    messageRange: 'ALL',
    businessId: -1,
    businessName: '',
    businessRemark: '',
    receiver: -1,
  });
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const editorContextRef = useRef<{
    context: any;
    getEditorContent: () => string;
  }>({
    context: undefined,
    getEditorContent: () => '',
  });
  const context = useContext(MessageAdminContext);
  const metadata = context.metadata!;
  const queryClient = useQueryClient();

  const sendMessageMutation = useMutation(
    async (variables: TBody<ISendMessageBody>) => {
      await sendMessage(variables);
    },
  );

  useEffect(() => {
    const differences = diff(
      {
        name: '',
        content: '',
        messageRange: 'ALL',
        businessId: -1,
        businessName: '',
        businessRemark: '',
        receiver: -1,
      },
      form,
    );
    setDifferenceData(differences);
  }, [form]);

  async function onSubmit(e: FormEvent<HTMLFormElement>) {
    try {
      e.preventDefault();
      e.stopPropagation();

      checkForm();
      const body = getFilterData(getDiffData(differenceData));
      if (isEmpty(body)) {
        show({
          type: 'DANGER',
          message: '新增消息失败，数据不存在',
        });
        return;
      }

      if (body.businessId === -1) {
        delete body.businessId;
      }

      if (body.receiver === -1) {
        delete body.receiver;
      }

      const messageRange = form.messageRange;
      const content = getEditorContent();
      await sendMessageMutation.mutateAsync({
        data: {
          ...(body as any),
          content,
          messageRange,
        },
      });
      clearData();

      show({
        type: 'SUCCESS',
        message: '保存完成',
      });
    } catch (e) {
      sendMessageMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function getEditorContent() {
    return editorContextRef.current.getEditorContent();
  }

  function clearData() {
    setForm(cleanFormData(form));
    setDifferenceData([]);
  }

  function checkForm() {
    const { name, messageRange, receiver, businessId } = form;

    if (!name) {
      throw '消息标题不能为空';
    }

    if (businessId !== -1 && businessId && !isNum(businessId)) {
      throw '请正确输入消息业务 Id';
    }

    if (!messageRange) {
      throw '消息范围不能为空';
    } else if (messageRange === 'USER') {
      if (receiver === -1) {
        throw '请正确输入消息接收者 Id';
      }

      if (!receiver || !isNum(receiver)) {
        throw '请正确输入消息接收者 Id';
      }
    }

    if (!getEditorContent()) {
      throw '消息内容不能为空';
    }
  }

  function onChange(
    e: ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>,
  ) {
    const name = e.target.name;
    const value = e.target.value;

    if (name === 'businessId') {
      if (isNum(value)) {
        setForm({ ...form, businessId: parseInt(value) });
      } else {
        setForm({ ...form, businessId: -1 });
      }
    } else if (name === 'receiver') {
      if (isNum(value)) {
        setForm({ ...form, receiver: parseInt(value) });
      } else {
        setForm({ ...form, receiver: -1 });
      }
    } else {
      setForm({ ...form, [name]: value });
    }
  }

  function onClickReturn() {
    if (typeof context.setIsCreate === 'function') {
      if (context.queryKey) {
        try {
          queryClient.refetchQueries(
            { queryKey: context.queryKey },
            { throwOnError: true },
          );
        } catch (e) {
          show({
            type: 'DANGER',
            message: e,
          });
        }
      }

      context.setIsCreate(false);
    }
  }

  return (
    <div className="row">
      <div className="col">
        <div className="card">
          <div className="card-header bg-transparent text-muted">
            <div className="row row-cols-auto justify-content-between">
              <div className="col">
                <div>
                  <i className="bi bi-plus-lg me-2"></i>
                  新增消息
                </div>
              </div>
              <div className="col">
                <div>
                  <i
                    onClick={onClickReturn}
                    className="bi bi-arrow-return-left cursor-pointer text-primary"
                  ></i>
                </div>
              </div>
            </div>
          </div>
          <div className="card-body">
            <form onSubmit={onSubmit} className="vstack gap-4">
              <div>
                <label className="form-label">标题</label>
                <textarea
                  rows={1}
                  name="name"
                  value={form.name}
                  onChange={onChange}
                  className="form-control"
                  aria-describedby="name"
                  placeholder="请输入消息标题"
                />
              </div>

              <div>
                <label className="form-label">范围</label>
                <select
                  name="messageRange"
                  value={form.messageRange}
                  onChange={onChange}
                  className="form-select"
                  aria-describedby="messageRange"
                  placeholder="请选择消息范围"
                >
                  <option disabled>请选择消息范围</option>
                  <option value="ALL">全局</option>
                  <option value="USER">用户</option>
                </select>
              </div>

              {form.messageRange === 'USER' && (
                <div>
                  <label className="form-label">接收者</label>
                  <input
                    type="text"
                    name="receiver"
                    value={form.receiver === -1 ? '' : form.receiver + ''}
                    onChange={onChange}
                    className="form-control"
                    aria-describedby="receiver"
                    placeholder="请输入接收者 Id"
                  />
                </div>
              )}

              <div>
                <label className="form-label">业务 Id</label>
                <input
                  type="text"
                  name="businessId"
                  value={form.businessId === -1 ? '' : form.businessId + ''}
                  onChange={onChange}
                  className="form-control"
                  aria-describedby="businessId"
                  placeholder="请输入业务 Id"
                />
              </div>

              <div>
                <label className="form-label">业务名称</label>
                <input
                  type="text"
                  name="businessName"
                  value={form.businessName}
                  onChange={onChange}
                  className="form-control"
                  aria-describedby="businessName"
                  placeholder="请输入业务名称"
                />
              </div>

              <div>
                <label className="form-label">业务备注</label>
                <input
                  type="text"
                  name="businessRemark"
                  value={form.businessRemark}
                  onChange={onChange}
                  className="form-control"
                  aria-describedby="businessRemark"
                  placeholder="请输入业务备注"
                />
              </div>

              <div>
                <label className="form-label">内容</label>
                <Editor
                  metadata={metadata}
                  type="message"
                  ref={editorContextRef}
                />
              </div>

              <button
                type="submit"
                disabled={sendMessageMutation.isLoading}
                className="btn btn-primary w-25 my-4"
              >
                {sendMessageMutation.isLoading && (
                  <span
                    className="spinner-border spinner-border-sm me-2"
                    role="status"
                    aria-hidden="true"
                  ></span>
                )}
                保存
              </button>
            </form>
          </div>
        </div>
      </div>
    </div>
  );
}
